package com.utils.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

public class HttpUtils {

    /**
     * 发送get请求
     *
     * @param url      请求路径
     * @param urlParam url参数 ?id=1&name=2
     * @param headers  请求头
     * @return String
     */
    public static String httpGet(String url, Map<String, Object> urlParam, Map<String, String> headers) {
        //1.创建client与response
        CloseableHttpClient client = HttpClientBuilder.create().build();
        //2.解析参数
        url = addGetParam(url, urlParam);
        //3.创建httpGet请求
        HttpGet httpGet = new HttpGet(url);
        return getString(client, httpGet, headers);
    }

    /**
     * 发送post请求
     *
     * @param url       请求路径
     * @param urlParam  url参数 ?id=1&name=2
     * @param bodyParam 请求体参数
     * @param headers   请求头
     * @return String
     */
    public static String httpPost(String url, Map<String, Object> urlParam, Object bodyParam, Map<String, String> headers) {
        //1.创建client与response
        CloseableHttpClient client = HttpClientBuilder.create().build();
        //2.创建httpPost请求
        url = addGetParam(url, urlParam);
        HttpPost httpPost = new HttpPost(url);
        //3.设置参数
        addBodyParam(bodyParam, httpPost);
        return getString(client, httpPost, headers);
    }


    /**
     * 以post请求的形式发送byte[] 文件
     *
     * @param url       请求路径
     * @param file      发送的文件
     * @param urlParam  url参数 ?id=1&name=2
     * @param bodyParam 请求体参数
     * @param headers   请求头
     * @return String
     */
    public static String httpPostBinaryFile(String url, File file, Map<String, Object> urlParam, Object bodyParam, Map<String, String> headers) {
        //1.创建client与response
        CloseableHttpClient client = HttpClientBuilder.create().build();
        //2.创建httpPost请求
        url = addGetParam(url, urlParam);
        HttpPost httpPost = new HttpPost(url);
        //3.设置参数
        addBinaryFile(file, httpPost);
        addBodyParam(bodyParam, httpPost);
        return getString(client, httpPost, headers);
    }

    private static String addGetParam(String url, Map<String, Object> urlParam) {
        return url + httpGetParam(urlParam);
    }

    private static void addBinaryFile(File file, HttpPost httpPost) {
        if (file == null) {
            throw new NullPointerException();
        } else {
            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
            builder.addBinaryBody("file", file, ContentType.MULTIPART_FORM_DATA, file.getName());
            httpPost.setEntity(builder.build());
        }
    }

    private static void addBodyParam(Object bodyParam, HttpPost httpPost) {
        if (bodyParam != null) {
            StringEntity entity = new StringEntity(JSON.toJSONString(bodyParam), ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
        }
    }


    private static String getString(CloseableHttpClient client, HttpRequestBase httpRequestBase, Map<String, String> headers) {
        CloseableHttpResponse response = null;
        //4.设置请求头
        addHeaders(httpRequestBase, headers);
        try {
            //5.发送请求
            response = client.execute(httpRequestBase);
            //6.获得返回内容
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity, "UTF-8");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                if (httpRequestBase != null) {
                    httpRequestBase.releaseConnection();
                }
                if (client != null) {
                    client.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    public static void addHeaders(HttpRequestBase httpRequestBase, Map<String, String> headers) {
        if (headers != null && !headers.isEmpty()) {
            Iterator<Map.Entry<String, String>> entryIterator = headers.entrySet().stream().iterator();
            if (entryIterator.hasNext()) {
                Map.Entry<String, String> next = entryIterator.next();
                httpRequestBase.setHeader(next.getKey(), next.getValue());
            }
        }
    }

    public static String httpGetParam(Map<String, Object> map) {
        if (map != null && !map.isEmpty()) {
            StringBuilder param = new StringBuilder("?");
            for (String key : map.keySet()) {
                param.append(key).append("=").append(map.get(key)).append("&");
            }
            return param.substring(0, param.length() - 1);
        }
        return "";
    }


    public static void main(String[] args) {
//        File file = new File("C:\\Users\\dbgs\\Pictures\\啊.jpg");
//        String s = httpPostBinaryFile("http://21.117.67.59:11014/file/upload", file, null, null, null);
//        System.out.println(s);

        String s1 = httpGet("https://api.bilibili.com/x/web-interface/nav", null, null);
        JSONObject jsonObject = JSON.parseObject(s1);
        System.out.println(jsonObject);
        System.out.println(jsonObject.getInteger("code"));
    }

}
